home *** CD-ROM | disk | FTP | other *** search
- #include "kant parser.h"
- #include "text twiddling.h"
- #include "util.h"
- #include "program globals.h"
- #include "cancel.h"
- #include "environment.h"
- #include "window layer.h"
-
- static void SafeDisposeHandle(Handle theHandle);
- static unsigned char GetTheCharacter(short *currentPosition);
- static void RememberCharacter(unsigned char theChar);
- static enum ErrorType GetReferenceName(Str255 theReferenceName, short *endPosition);
- static enum ErrorType GetReferenceID(Str255 theReferenceName, short *refNum, short *numOptions);
- static enum ErrorType InstantiateReference(Str255 theText, short refNum, short numOptions);
- static enum ErrorType ReplaceTheText(short start, short end, Str255 theStr);
- static enum ErrorType GetChoiceText(Str255 theText, short start, short *end, Boolean chooseFirst);
- static enum ErrorType GetOptionalText(Str255 theText, short start, short *end, Boolean chooseFirst);
-
- static TEHandle gTheTEHandle;
- static WindowPtr gTheWindow;
- static short gTheWindowIndex;
- static short gTheTEPosition;
- static short gTheEndPosition;
- static short gTheTELength;
- static unsigned char gRememberedChar;
- static Boolean gRememberedCharValid;
-
- void InitTheParser(WindowPtr theWindow, short rawStart, short rawEnd)
- {
- gTheTEHandle=GetWindowTE(theWindow);
- gTheWindow=theWindow;
- gTheWindowIndex=GetWindowIndex(theWindow);
- gTheTEPosition=rawStart;
- gTheEndPosition=rawEnd;
- gTheTELength=(**gTheTEHandle).teLength;
- gRememberedChar=0x00;
- gRememberedCharValid=FALSE;
- }
-
- enum ErrorType ParseLoop(void)
- {
- unsigned char theChar;
- short currentPosition, endPosition;
- Str255 theReferenceName;
- enum ErrorType theError;
- Str255 theText;
- short numOptions;
- short refNum;
-
- theChar=' ';
- while (theChar!=0xFF) /* end of text */
- {
- theChar=GetTheCharacter(¤tPosition);
- switch (theChar)
- {
- case '&': /* reference */
- theError=GetReferenceName(theReferenceName, &endPosition);
- if (theError!=kNoError)
- return theError;
- theError=GetReferenceID(theReferenceName, &refNum, &numOptions);
- if (theError!=kNoError)
- return theError;
- if (numOptions==0)
- return kNoInstantiations;
- theError=InstantiateReference(theText, refNum, numOptions);
- if (theError!=kNoError)
- return theError;
- theError=ReplaceTheText(currentPosition, endPosition, theText);
- if (theError!=kNoError)
- return theError;
- break;
- case '[': /* choice */
- theError=GetChoiceText(theText, currentPosition, &endPosition,
- (TickCount()%2) ? TRUE : FALSE);
- if (theError!=kNoError)
- return theError;
- theError=ReplaceTheText(currentPosition, endPosition, theText);
- if (theError!=kNoError)
- return theError;
- break;
- case '<': /* optional text */
- theError=GetOptionalText(theText, currentPosition, &endPosition,
- (TickCount()%2) ? TRUE : FALSE);
- if (theError!=kNoError)
- return theError;
- theError=ReplaceTheText(currentPosition, endPosition, theText);
- if (theError!=kNoError)
- return theError;
- break;
- case '#': /* next letter capitalized */
- theChar=GetTheCharacter(&endPosition);
- if (((theChar>='a') && (theChar<='z')) ||
- ((theChar>='A') && (theChar<='Z')))
- {
- theText[0]=0x01;
- theText[1]=theChar&0xdf;
- theError=ReplaceTheText(currentPosition, endPosition+1, theText);
- if (theError!=kNoError)
- return theError;
- }
- else RememberCharacter(theChar);
- break;
- case '\\': /* backslash character */
- theChar=GetTheCharacter(&endPosition);
- switch (theChar)
- {
- case 'r':
- case 'R':
- theText[0]=0x01;
- theText[1]='\r';
- break;
- case 't':
- case 'T':
- theText[0]=0x01;
- theText[1]='\t';
- break;
- case '0':
- theText[0]=0x00;
- break;
- default:
- return kBadBackslash;
- break;
- }
- theError=ReplaceTheText(currentPosition, endPosition+1, theText);
- if (theError!=kNoError)
- return theError;
- break;
- }
- }
-
- return kNoError;
- }
-
- /* --------------------------------------------------------- */
- /* the rest of these functions are internal to kant parser.c */
- /* --------------------------------------------------------- */
-
- static void SafeDisposeHandle(Handle theHandle)
- {
- if (theHandle!=0L)
- DisposeHandle(theHandle);
- }
-
- static unsigned char GetTheCharacter(short *currentPosition)
- {
- if (gRememberedCharValid)
- {
- gRememberedCharValid=FALSE;
- *currentPosition=gTheTEPosition-1;
-
- return gRememberedChar;
- }
- else
- {
- *currentPosition=gTheTEPosition;
-
- if (gTheTEPosition<gTheTELength)
- {
- return (*(**gTheTEHandle).hText)[gTheTEPosition++];
- }
- else
- {
- return 0xFF;
- }
- }
- }
-
- static void RememberCharacter(unsigned char theChar)
- {
- gRememberedChar=theChar;
- gRememberedCharValid=TRUE;
- }
-
- static enum ErrorType GetReferenceName(Str255 theReferenceName, short *endPosition)
- {
- unsigned char theChar;
- short dummyPosition;
-
- theReferenceName[0]=0x00;
- theChar=GetTheCharacter(&dummyPosition);
- while ((theChar!=0xFF) &&
- (((theChar>='a') && (theChar<='z')) ||
- ((theChar>='A') && (theChar<='Z')) ||
- ((theChar>='0') && (theChar<='9')) ||
- (theChar=='-') || (theChar=='_')))
- {
- theReferenceName[++theReferenceName[0]]=theChar;
- theChar=GetTheCharacter(&dummyPosition);
- }
-
- RememberCharacter(theChar);
-
- if (theReferenceName[0]==0x00)
- return kNoReferenceName;
-
- *endPosition=dummyPosition;
- return kNoError;
- }
-
- static enum ErrorType GetReferenceID(Str255 theReferenceName, short *refNum, short *numOptions)
- {
- Handle theResHandle;
- Str255 name;
- ResType theType;
-
- SetResLoad(TRUE);
- theResHandle=Get1NamedResource('STR#', theReferenceName);
- if (theResHandle==0L)
- return kBadReference;
-
- *numOptions=**((short**)theResHandle);
- GetResInfo(theResHandle, refNum, &theType, name);
- ReleaseResource(theResHandle);
-
- return kNoError;
- }
-
- static enum ErrorType InstantiateReference(Str255 theText, short refNum, short numOptions)
- {
- GetIndString(theText, refNum, 1+((Random()&0x7fff)%numOptions));
- return kNoError;
- }
-
- static enum ErrorType ReplaceTheText(short start, short end, Str255 theStr)
- {
- long textLength;
- unsigned char dummy;
- short dummyPos;
- long dummyLong;
-
- TESetSelect(start, end, gTheTEHandle);
- TEDelete(gTheTEHandle);
- textLength=theStr[0];
- if (textLength>0)
- TEInsert(&theStr[1], textLength, gTheTEHandle);
- TESelView(gTheTEHandle);
- SetWindowIsModified(gTheWindow, TRUE);
- AdjustVScrollBar(GetWindowVScrollBar(gTheWindow), gTheTEHandle);
- gRememberedCharValid=FALSE;
- gTheTELength=(**gTheTEHandle).teLength;
- gTheTEPosition=start-1;
- if (gTheTEPosition<0)
- gTheTEPosition=0;
- else
- {
- dummy=GetTheCharacter(&dummyPos);
- if (dummy=='#')
- RememberCharacter(dummy);
- }
-
- if (!DealWithOtherPeople())
- return kUserCancelled;
- if (!gInProgress)
- return kUserCancelled;
- if (!IndWindowExistsQQ(gTheWindowIndex))
- return kUserCancelled;
-
- Delay(gSpeedDelay, &dummyLong);
-
- return kNoError;
- }
-
- static enum ErrorType GetChoiceText(Str255 theText, short start, short *end, Boolean chooseFirst)
- {
- short level;
- unsigned char theChar;
- short endOfFirstChoice;
- short thePosition;
-
- level=1;
- theText[0]=0x00;
- theChar=GetTheCharacter(&thePosition);
- endOfFirstChoice=-1;
- while (theChar!=0xFF)
- {
- if ((chooseFirst && (endOfFirstChoice==-1)) ||
- (!chooseFirst && (endOfFirstChoice!=-1)))
- {
- theText[++theText[0]]=theChar;
- }
-
- switch (theChar)
- {
- case '[':
- level++;
- break;
- case ']':
- level--;
- if (level==0)
- {
- if (endOfFirstChoice==-1)
- return kBadChoiceFormat;
- *end=thePosition+1;
- theText[0]--;
- return kNoError;
- }
- break;
- case '|':
- if (level==1)
- {
- if (endOfFirstChoice==-1)
- endOfFirstChoice=thePosition;
- else
- return kBadChoiceFormat;
- }
- break;
- }
-
- theChar=GetTheCharacter(&thePosition);
- }
-
- return kBadChoiceFormat;
- }
-
- static enum ErrorType GetOptionalText(Str255 theText, short start, short *end, Boolean useIt)
- {
- short level;
- unsigned char theChar;
- short thePosition;
-
- level=1;
- theText[0]=0x00;
- theChar=GetTheCharacter(&thePosition);
- while (theChar!=0xFF)
- {
- if (useIt)
- {
- theText[++theText[0]]=theChar;
- }
-
- switch (theChar)
- {
- case '<':
- level++;
- break;
- case '>':
- level--;
- if (level==0)
- {
- *end=thePosition+1;
- if (useIt)
- theText[0]--;
- return kNoError;
- }
- break;
- }
-
- theChar=GetTheCharacter(&thePosition);
- }
-
- return kBadOptionalFormat;
- }
-